package com.yida.gwj.deposit.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.yida.common.core.constant.SecurityConstants;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.PageUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.core.utils.file.FileTypeUtils;
import com.yida.common.core.utils.poi.ExcelUtil;
import com.yida.common.core.web.page.TableDataInfo;
import com.yida.common.redis.service.RedisService;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfCalculateData;
import com.yida.gwj.api.domain.GwjConfCalculateType;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.service.RemoteGwjConfigService;
import com.yida.gwj.common.constant.GwjCacheConstants;
import com.yida.gwj.common.constant.GwjConstants;
import com.yida.gwj.common.constant.GwjCustomImportConstants;
import com.yida.gwj.common.domain.GwjBaseBuild;
import com.yida.gwj.common.domain.GwjBaseBusinessBuild;
import com.yida.gwj.common.domain.GwjBaseBusinessNum;
import com.yida.gwj.common.domain.GwjBaseCommunity;
import com.yida.gwj.common.domain.GwjBaseHouse;
import com.yida.gwj.common.domain.GwjBaseOwner;
import com.yida.gwj.common.domain.dto.GwjUserDTO;
import com.yida.gwj.common.domain.request.GwjBaseBuildRequest;
import com.yida.gwj.common.enums.GwjBusinessFlagType;
import com.yida.gwj.common.enums.GwjBusinessHouseStatus;
import com.yida.gwj.common.enums.GwjBusinessStatus;
import com.yida.gwj.common.enums.GwjCheckAccountStatus;
import com.yida.gwj.common.enums.StepConfigInfoEnum;
import com.yida.gwj.common.mapper.GwjBaseBuildMapper;
import com.yida.gwj.common.mapper.GwjBaseCommunityMapper;
import com.yida.gwj.common.service.IGwjBaseBusinessNumService;
import com.yida.gwj.common.service.IGwjBaseHouseService;
import com.yida.gwj.common.service.IGwjBaseOwnerService;
import com.yida.gwj.common.service.IGwjImpSqeService;
import com.yida.gwj.common.utils.GwjCalculateFormulaUtil;
import com.yida.gwj.common.utils.GwjConvertUtil;
import com.yida.gwj.deposit.domain.GwjDepositBusiness;
import com.yida.gwj.deposit.domain.GwjDepositBusinessBuild;
import com.yida.gwj.deposit.domain.GwjDepositBusinessCommunity;
import com.yida.gwj.deposit.domain.GwjDepositBusinessDetail;
import com.yida.gwj.deposit.domain.GwjDepositBusinessHouse;
import com.yida.gwj.deposit.domain.GwjDepositBusinessLog;
import com.yida.gwj.deposit.domain.GwjDepositBusinessMoney;
import com.yida.gwj.deposit.domain.dto.GwjCommunityHouseholdHouseRecordDTO;
import com.yida.gwj.deposit.domain.dto.GwjCommunityHouseholdRecordTopDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositBuildRecordDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositBusinessDetailDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositBusinessHouseListDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositBusinessHouseTopDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositCommunityDetailDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositMoneyDetailDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositPageDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositPaymentDetailDTO;
import com.yida.gwj.deposit.domain.dto.GwjDepositRecordTopDTO;
import com.yida.gwj.deposit.domain.dto.GwjUnitDepositBuildDetailDTO;
import com.yida.gwj.deposit.domain.dto.GwjUnitDepositDetailDTO;
import com.yida.gwj.deposit.domain.request.GwjCalculateRequest;
import com.yida.gwj.deposit.domain.request.GwjDepositBusinessBuildRequest;
import com.yida.gwj.deposit.domain.request.GwjDepositBusinessCommunityRequest;
import com.yida.gwj.deposit.domain.request.GwjDepositBusinessLogRequest;
import com.yida.gwj.deposit.domain.request.GwjDepositBusinessMoneyRequest;
import com.yida.gwj.deposit.domain.request.GwjDepositBusinessRequest;
import com.yida.gwj.deposit.domain.request.GwjPublicAccountRequest;
import com.yida.gwj.deposit.domain.request.GwjPublicBusinessHouseRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositBusinessDetailEditRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositCommunityAndBuildEditRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositCommunityEditRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositEditBuildCalculateRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositEditCalculateHouseRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositEditMoneyCalculateRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositEditRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositRequest;
import com.yida.gwj.deposit.domain.request.GwjUnitDepositSubmitRequest;
import com.yida.gwj.deposit.domain.vo.GwjUnitDepositBusinessExcelVo;
import com.yida.gwj.deposit.enums.GwjDepositStatusEnum;
import com.yida.gwj.deposit.enums.GwjUnitDepositStepEnum;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessBuildMapper;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessCommunityMapper;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessDetailMapper;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessHouseMapper;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessMapper;
import com.yida.gwj.deposit.mapper.GwjDepositBusinessMoneyMapper;
import com.yida.gwj.deposit.service.IGwjDepositBusinessLogService;
import com.yida.gwj.deposit.service.IGwjDepositBusinessService;
import com.yida.gwj.deposit.service.IGwjUnitDepositBusinessService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;

/**
 * @Description 业务（单位批量缴费）ServiceImpl 实现类
 * @Author wws
 * @Date 2023-02-17
 */
@Service
public class GwjUnitDepositBusinessServiceImpl implements IGwjUnitDepositBusinessService {

    @Autowired
    private IGwjDepositBusinessService gwjDepositBusinessService;

    @Autowired
    private GwjDepositBusinessMapper gwjDepositBusinessMapper;

    @Autowired
    private GwjBaseCommunityMapper gwjBaseCommunityMapper;

    @Autowired
    private GwjBaseBuildMapper gwjBaseBuildMapper;

    @Autowired
    private RemoteGwjConfigService remoteGwjConfigService;

    @Autowired
    private IGwjBaseBusinessNumService businessNumService;

    @Autowired
    private GwjDepositBusinessMoneyMapper gwjDepositBusinessMoneyMapper;

    @Autowired
    private GwjDepositBusinessCommunityMapper gwjDepositBusinessCommunityMapper;

    @Autowired
    private GwjDepositBusinessBuildMapper gwjDepositBusinessBuildMapper;

    @Autowired
    private IGwjDepositBusinessLogService gwjDepositBusinessLogService;

    @Autowired
    private IGwjBaseHouseService gwjBaseHouseService;

    @Autowired
    private GwjDepositBusinessHouseMapper gwjDepositBusinessHouseMapper;

    @Autowired
    private GwjDepositBusinessDetailMapper gwjDepositBusinessDetailMapper;

    @Autowired
    private IGwjBaseOwnerService baseOwnerService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IGwjImpSqeService gwjImpSqeService;

    /**
     * 分页查询
     *
     * @param gwjDepositBusiness 查询参数
     * @return
     */
    @Override
    public List<GwjDepositPageDTO> getPage(GwjDepositBusiness gwjDepositBusiness) {
        // 设置业务标识
        gwjDepositBusiness.setBizFlagId(GwjBusinessFlagType.UNIT_DEPOSIT.getCode());
        // 设置查询参数
        PageUtils.startPage();
        // 查询分页对象
        return gwjDepositBusinessMapper.selectGwjDepositBusinessPage(gwjDepositBusiness);
    }

    /**
     * 保存
     *
     * @param gwjUnitDepositRequest 单位批量缴费参数
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long save(GwjUnitDepositRequest gwjUnitDepositRequest) {
        // 获取参数
        GwjDepositBusinessRequest businessRequest = gwjUnitDepositRequest.getBusinessRequest();
        businessRequest.setBizFlagId(GwjBusinessFlagType.UNIT_DEPOSIT.getCode());
        GwjDepositBusinessMoneyRequest moneyRequest = gwjUnitDepositRequest.getMoneyRequest();
        GwjDepositBusinessCommunityRequest communityRequest = gwjUnitDepositRequest.getCommunityRequest();
        List<GwjDepositBusinessBuildRequest> buildRequests = gwjUnitDepositRequest.getBuildRequests();
        // 查询基础参数
        if (ObjectUtil.isEmpty(communityRequest.getCommunityId())) {
            throw new ServiceException("社区信息主键不能为空");
        }
        GwjBaseCommunity baseCommunity = gwjBaseCommunityMapper.selectGwjBaseCommunityByGwjBaseCommunityId(communityRequest.getCommunityId());
        if (ObjectUtil.isEmpty(baseCommunity)) {
            throw new ServiceException("未查询到对应社区信息");
        }
        Long[] buildIds = buildRequests.stream().map(GwjDepositBusinessBuildRequest::getBuildId).toArray(Long[]::new);
        if (ObjectUtil.isEmpty(buildIds)) {
            throw new ServiceException("楼栋信息主键不能为空");
        }
        List<GwjBaseBuild> baseBuilds = gwjBaseBuildMapper.selectGwjBaseBuildByBuildIdList(buildIds);
        if (ObjectUtil.isEmpty(baseBuilds)) {
            throw new ServiceException("未查询到对应小区信息");
        }
        if (buildRequests.size() != baseBuilds.size()) {
            throw new ServiceException("小区信息有误，请重新上传");
        }
        // 处理保存参数
        GwjDepositBusiness business = new GwjDepositBusiness();
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        GwjDepositBusinessCommunity community = new GwjDepositBusinessCommunity();
        List<GwjDepositBusinessBuild> builds = new ArrayList<GwjDepositBusinessBuild>(baseBuilds.size());

        // ===============================================处理业务参数========================================
        // 拷贝业务参数
        BeanUtil.copyProperties(businessRequest, business);
        // 设置业务编号
        GwjBaseBusinessNum businessNum = businessNumService.getNextNum(communityRequest.getAreaId(), business.getBizFlagId());
        // 业务编号
        business.setBizNum(Convert.toLong(businessNum));
        // 设置流程号
        business.setFlowId(remoteGwjConfigService.selectGwjConfBusinessFlagByBizFlagId(business.getBizFlagId(), SecurityConstants.INNER).getData().getFlowId());
        // 设置区域编码
        business.setAreaId(communityRequest.getAreaId());
        // 设置申请时间
        business.setApplicantTime(DateUtils.getNowDate());
        // 设置步骤
        business.setStepId(GwjUnitDepositStepEnum.ACCEPTED.getStepId());
        // 保存业务
        if (1 != gwjDepositBusinessMapper.insertGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息保存失败");
        }

        // ===============================================处理业务小区参数========================================
        // 拷贝业务小区参数
        BeanUtil.copyProperties(baseCommunity, community);
        BeanUtil.copyProperties(communityRequest, community);
        // 赋值业务编号
        community.setBizId(business.getBizId());
        // 保存业务小区信息
        if (1 != gwjDepositBusinessCommunityMapper.insertGwjDepositBusinessCommunity(community)) {
            throw new ServiceException("业务小区信息保存失败");
        }

        // ===============================================处理业务楼栋参数========================================
        // 拷贝业务楼栋信息参数
        for (GwjBaseBuild baseBuild : baseBuilds) {
            GwjDepositBusinessBuild build = new GwjDepositBusinessBuild();
            BeanUtil.copyProperties(baseBuild, build);
            build.setBizCommunityId(community.getBizCommunityId());
            build.setBizId(business.getBizId());
            builds.add(build);
        }
        for (GwjDepositBusinessBuildRequest buildRequest : buildRequests) {
            builds = builds.stream().map(build -> {
                if (buildRequest.getBuildId().equals(build.getBuildId())) {
                    BeanUtil.copyProperties(buildRequest, build);
                }
                return build;
            }).collect(Collectors.toList());
        }
        // 保存业务楼栋信息
        if (0 == gwjDepositBusinessBuildMapper.insertGwjDepositBusinessBuilds(builds)) {
            throw new ServiceException("业务楼栋保存失败");
        }

        // ===============================================处理业务房屋参数========================================
        // 拉取楼栋房屋信息
        String[] buildCode = builds.stream().map(GwjDepositBusinessBuild::getBuildCode).toArray(String[]::new);
        Map<String, Long> buildMap = builds.stream().collect(Collectors.toMap(GwjBaseBusinessBuild::getBuildCode, GwjDepositBusinessBuild::getBuildId));
        if (ObjectUtil.isEmpty(buildCode)) {
            throw new ServiceException("楼栋编号不能为空");
        }
        // 查询业务房屋信息
        List<GwjBaseHouse> baseHouses = gwjBaseHouseService.selectGwjBaseListByBuildCodesAndAreaId(buildCode, community.getAreaId());
        // 拷贝业务房屋参数
        List<GwjDepositBusinessHouse> houses = baseHouses.stream().map(baseHouse -> {
            GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
            BeanUtil.copyProperties(baseHouse, house);
            house.setBizId(business.getBizId());
            house.setBuildId(buildMap.get(house.getBuildCode()));
            house.setSelectFlag(GwjConstants.YES);
            house.setDepositMoney(new BigDecimal("0.00"));
            house.setDepositSize(null != house.getActualSize() && !new BigDecimal("0.00").equals(house.getActualSize()) ? house.getActualSize() : null != house.getForecastSize() && !new BigDecimal("0.00").equals(house.getForecastSize()) ? house.getForecastSize() : new BigDecimal("0.00"));
            return house;
        }).collect(Collectors.toList());
        // 保存业务房屋信息
        if (0 == gwjDepositBusinessHouseMapper.insertGwjDepositBusinessHouses(houses)) {
            throw new ServiceException("业务房屋保存失败");
        }

        // ===============================================处理业务金额参数========================================
        // 拷贝业金额参数
        BeanUtil.copyProperties(moneyRequest, money);
        // 赋值业务编号
        money.setBizId(business.getBizId());
        money.setAreaId(business.getAreaId());
        // 设置参数默认值
        money.setLedgerType(GwjConstants.INCOME);
        // 设置缴存户数
        money.setTotalOwner(Long.valueOf(houses.size()));
        // 保存业务金额
        if (1 != gwjDepositBusinessMoneyMapper.insertGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息保存失败");
        }

        // 保存业务日志
        gwjDepositBusinessLogService.addSaveLog(business);
        return business.getBizId();
    }

    /**
     * 查询资金分户房屋列表
     *
     * @param gwjDepositBusinessHouse 房屋查询参数
     * @return
     */
    @Override
    public TableDataInfo getHouseDetailList(GwjDepositBusinessHouse gwjDepositBusinessHouse) {

        TableDataInfo tableDataInfo = new TableDataInfo();
        // 校验参数
        if (ObjectUtil.isEmpty(gwjDepositBusinessHouse.getBizId())) {
            throw new ServiceException("业务主键不能为空");
        }
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(gwjDepositBusinessHouse.getBizId());
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money.getCalculateTypeId())) {
            throw new ServiceException("当前业务未选择缴存标准");
        }
        if (StringUtils.isNotBlank(gwjDepositBusinessHouse.getBuildCode())) {
            gwjDepositBusinessHouse.setBuildCodes(com.yida.common.core.text.Convert.toStrArray(gwjDepositBusinessHouse.getBuildCode()));
            gwjDepositBusinessHouse.setBuildCode(null);
        }
        Long total = gwjDepositBusinessHouseMapper.countTotalSize(gwjDepositBusinessHouse);
        PageUtils.startPage();
        // 获取房屋信息
        List<GwjDepositBusinessHouseListDTO> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHousePage(gwjDepositBusinessHouse);
        GwjDepositBusinessBuild gwjDepositBusinessBuild = new GwjDepositBusinessBuild();
        gwjDepositBusinessBuild.setBizId(gwjDepositBusinessHouse.getBizId());
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildList(gwjDepositBusinessBuild);
        Map<String, GwjDepositBusinessBuild> buildMap = builds.stream().collect(Collectors.toMap(GwjBaseBusinessBuild::getBuildCode, Function.identity()));
        Map<Long, GwjConfCalculateType> calculateTypeHashMap = new HashMap<Long, GwjConfCalculateType>(builds.size());
        for (GwjDepositBusinessBuild item : builds) {
            if (GwjConstants.YES.equals(item.getPublicFlag())) {
                continue;
            }
            GwjConfCalculateType confCalculateType = remoteGwjConfigService.selectGwjConfCalculateTypeByCalculateTypeId(Long.valueOf(item.getCalculateDataId()), SecurityConstants.INNER).getData();
            if (ObjectUtil.isEmpty(confCalculateType)) {
                throw new ServiceException("未查询到对应缴存标准");
            }
            calculateTypeHashMap.put(confCalculateType.getCalculateTypeId(), confCalculateType);
        }
        // 查询其他计算标准
        if (ObjectUtil.isEmpty(calculateTypeHashMap.get(GwjConstants.IMPORT_HOUSE_CALCULATE_ID))) {
            GwjConfCalculateType confCalculateType = remoteGwjConfigService.selectGwjConfCalculateTypeByCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID, SecurityConstants.INNER).getData();
            calculateTypeHashMap.put(confCalculateType.getCalculateTypeId(), confCalculateType);
        }
        String[] houseCode = null;
        Map<String, String> ownerMap = new HashMap<String, String>();
        if (ObjectUtil.isNotEmpty(houseList)) {
            houseCode = houseList.stream().map(GwjDepositBusinessHouseListDTO::getHouseCode).toArray(String[]::new);
        }
        if (ObjectUtil.isNotEmpty(houseCode)) {
            for (GwjBaseOwner owner : baseOwnerService.selectGwjBaseListByGwjBaseHouseCodes(houseCode, money.getAreaId())) {
                if (ObjectUtil.isEmpty(ownerMap.get(owner.getHouseCode()))) {
                    ownerMap.put(owner.getHouseCode(), owner.getOwnerName());
                } else {
                    List<String> ownerNameList = new ArrayList<String>(2);
                    ownerNameList.add(ownerMap.get(owner.getHouseCode()));
                    ownerNameList.add(owner.getOwnerName());
                    ownerMap.put(owner.getHouseCode(), StringUtils.join(ownerNameList, ","));
                }
            }

        }
        tableDataInfo.setRows(houseList.stream().map(house -> {
            GwjDepositBusinessHouseListDTO dto = new GwjDepositBusinessHouseListDTO();
            BeanUtil.copyProperties(house, dto);
            dto.setBuildName(null != buildMap.get(dto.getBuildCode()) ? buildMap.get(dto.getBuildCode()).getBuildName() : null);
            dto.setCalculateTypeName(null != calculateTypeHashMap.get(dto.getCalculateTypeId()) ? calculateTypeHashMap.get(dto.getCalculateTypeId()).getName() : null);
            dto.setOwnerName(ownerMap.get(dto.getHouseCode()));
            return dto;
        }).collect(Collectors.toList()));
        tableDataInfo.setTotal(total);
        tableDataInfo.setCode(200);
        tableDataInfo.setMsg("查询成功");
        // 赋值返回对象
        return tableDataInfo;
    }

    /**
     * 查询缴存清册
     *
     * @param bizId 业务主键
     * @return
     */
    @Override
    public List<GwjDepositBuildRecordDTO> getDepositRecord(Long bizId) {
        // 设置查询参数
        PageUtils.startPage();
        return gwjDepositBusinessBuildMapper.getDepositHouseRecord(bizId);
    }

    /**
     * 查询小区分户清册
     *
     * @param bizId 业务主键
     * @return
     */
    @Override
    public List<GwjCommunityHouseholdHouseRecordDTO> getCommunityHouseholdRecord(Long bizId) {
        // 设置查询参数
        PageUtils.startPage();
        return gwjDepositBusinessBuildMapper.getCommunityHouseholdHouseRecord(bizId);
    }

    /**
     * 签署意见
     *
     * @param businessLog 日志参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signOpinion(GwjDepositBusinessLog businessLog) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(businessLog.getBizId());
        // 保存日志
        businessLog.setStepId(business.getStepId());
        if (checkStepConfigInfo(business.getStepId(), StepConfigInfoEnum.SUBMIT_SIGN.getCode())) {
            throw new ServiceException("当前步骤不允许提交签署意见");
        }
        gwjDepositBusinessLogService.addSignOpinionLog(businessLog);
    }

    /**
     * 送件
     *
     * @param businessLog 日志参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void send(GwjDepositBusinessLog businessLog) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(businessLog.getBizId());
        // 修改当前办理人员
        business.setCurrentOperId(businessLog.getUserId());
        business.setCurrentOperName(businessLog.getRealName());
        gwjDepositBusinessMapper.updateGwjDepositBusiness(business);
        if (checkStepConfigInfo(business.getStepId(), StepConfigInfoEnum.SEND.getCode())) {
            throw new ServiceException("当前步骤不允许提交送件");
        }
        // 记录日志
        gwjDepositBusinessLogService.addSendLog(businessLog, business);
    }

    /**
     * 提交
     *
     * @param submitRequest 提交参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitBusiness(GwjUnitDepositSubmitRequest submitRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(submitRequest.getBizId());
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        // 校验参数
        // 校验业务小区信息
        GwjDepositBusinessCommunity gwjDepositBusinessCommunity = new GwjDepositBusinessCommunity();
        gwjDepositBusinessCommunity.setBizId(submitRequest.getBizId());
        GwjDepositBusinessCommunity community = gwjDepositBusinessCommunityMapper.selectGwjDepositBusinessCommunity(gwjDepositBusinessCommunity);
        if (ObjectUtil.isEmpty(community)) {
            throw new ServiceException("请先保存业务小区信息");
        }
        // 校验业务楼栋信息
        GwjDepositBusinessBuild gwjDepositBusinessBuild = new GwjDepositBusinessBuild();
        gwjDepositBusinessBuild.setBizId(submitRequest.getBizId());
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildList(gwjDepositBusinessBuild);
        if (ObjectUtil.isEmpty(builds)) {
            throw new ServiceException("请保存业务楼栋信息");
        }
        // 校验业务房屋信息
        GwjDepositBusinessHouse gwjDepositBusinessHouse = new GwjDepositBusinessHouse();
        gwjDepositBusinessHouse.setBizId(submitRequest.getBizId());
        List<GwjDepositBusinessHouse> houses = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(gwjDepositBusinessHouse);
        if (ObjectUtil.isEmpty(houses)) {
            throw new ServiceException("请保存业务房屋信息");
        }
        // 校验业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(submitRequest.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("请保存业务金额信息");
        }
        // 校验业务缴存明细信息
        if (business.getStepId().equals(GwjUnitDepositStepEnum.TRIAL.getStepId())) {
            // 重置总账、分账流水
            if (!gwjDepositBusinessService.removeLedger(business.getBizId())) {
                throw new ServiceException("总账、分账流水重置失败");
            }
            // 生成总账、分账流水
            if (!gwjDepositBusinessService.generateLedger(submitRequest.getBizId())) {
                throw new ServiceException("生成总账、分账流水失败");
            }
        }
        // 校验是否已财务对账
        if (business.getStepId().equals(GwjUnitDepositStepEnum.FINANCIAL_RECONCILIATION.getStepId())) {
            if (!GwjCheckAccountStatus.CHECK_SUCCESS.getCode().equals(money.getStatus())) {
                throw new ServiceException("请先完成财务对账");
            }
        }
        // 校验下一步骤
        GwjConfStep nextStep = remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.UNIT_DEPOSIT.getCode(), business.getStepId(), SecurityConstants.INNER).getData();
        if (ObjectUtil.isEmpty(nextStep)) {
            throw new ServiceException("当前案例已完结");
        }

        // 处理日志信息
        // 设置日志流程步骤,业务编号
        GwjDepositBusinessLogRequest businessLogRequest = submitRequest.getLogRequest();
        GwjDepositBusinessLog businessLog = new GwjDepositBusinessLog();
        BeanUtil.copyProperties(businessLogRequest, businessLog);
        // 设置日志步骤
        businessLog.setStepId(business.getStepId());
        // 设置日志业务主键
        businessLog.setBizId(business.getBizId());
        // 获取当前步骤所有配置
        List<String> configInfos = remoteGwjConfigService.selectGwjConfStepConfigInfoCodeListByBizFlagId(businessLog.getStepId(), SecurityConstants.INNER).getData();
        // 判断是否需要选收件人
        if (StringUtils.containsAny(configInfos, "submit_choose_user") && StringUtils.isAnyBlank(com.yida.common.core.text.Convert.toStr(businessLog.getUserId()), businessLog.getRealName())) {
            throw new ServiceException("请选择下一位收件人");
        }

        // 处理业务数据
        // 设置下一步步骤
        business.setStepId(nextStep.getStepId());
        // 设置下一步受理人员
        business.setCurrentOperId(StringUtils.isNull(businessLog.getUserId()) ? SecurityUtils.getUserId() : businessLog.getUserId());
        business.setCurrentOperName(StringUtils.isBlank(businessLog.getRealName()) ? SecurityUtils.getLoginUser().getSysUser().getRealName() : businessLog.getRealName());
        // 判断下一步骤是否为案例完结
        if (ObjectUtil.isNotEmpty(remoteGwjConfigService.selectNextGwjConfStepByFlagId(GwjBusinessFlagType.UNIT_DEPOSIT.getCode(), business.getStepId(), SecurityConstants.INNER).getData())) {
            // 设置业务状态
            business.setStatus(GwjBusinessStatus.NORMAL.getCode());
            // 更新业务日志
            gwjDepositBusinessLogService.addSubmitLog(businessLog, business);
        } else {
            // 同步业务数据至基础库
            if (ObjectUtil.isNotEmpty(houses)) {
                houses.forEach(house -> {
                    // 公用户做插入
                    if (GwjConstants.YES.equals(house.getPublicFlag())) {
                        // 判断所属楼栋是不是也是公用户
                        GwjDepositBusinessBuild depositBusinessBuild = new GwjDepositBusinessBuild();
                        depositBusinessBuild.setBuildCode(house.getBuildCode());
                        depositBusinessBuild.setBizId(business.getBizId());
                        GwjDepositBusinessBuild build = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuild(depositBusinessBuild);
                        if (ObjectUtil.isNotNull(build) && build.getPublicFlag().equals(GwjConstants.YES)) {
                            // 判断基础库是否已存在
                            if (ObjectUtil.isNull(gwjBaseBuildMapper.selectGwjBaseBuildByAreaIdAndBuildCode(business.getAreaId(), gwjDepositBusinessHouse.getBuildCode()))) {
                                // 插入
                                GwjBaseBuild baseBuild = GwjConvertUtil.convert(build, GwjBaseBuild.class);
                                baseBuild.setCommunityId(community.getCommunityId());
                                baseBuild.setCommunityName(community.getCommunityName());
                                gwjBaseBuildMapper.insertGwjBaseBuild(baseBuild);
                            }
                        }
                        GwjBaseHouse gwjBaseHouse = gwjBaseHouseService.selectGwjBaseHouseByGwjBaseHouseId(house.getHouseId());
                        if (ObjectUtil.isEmpty(gwjBaseHouse)) {
                            GwjBaseHouse baseHouse = GwjConvertUtil.convert(house, GwjBaseHouse.class);
                            BigDecimal depositMoney = house.getDepositMoney();
                            baseHouse.setDepositMoney(depositMoney);
                            // if (ObjectUtil.isEmpty(baseHouse.getUsedMoney()) ||
                            // baseHouse.getUsedMoney().equals(BigDecimal.ZERO)) {
                            // String configValue =
                            // com.yida.common.core.text.Convert.toStr(redisService.getCacheObject(GwjCacheConstants.GWJ_CONFIG_KEY
                            // + GwjCacheConstants.BLOCKED_MONEY_KEY));
                            // baseHouse.setBlockedMoney(depositMoney.multiply(new BigDecimal(configValue)));
                            // }
                            baseHouse.setCurrentMoney(depositMoney);
                            if (1 != gwjBaseHouseService.insertGwjBaseHouse(baseHouse)) {
                                throw new ServiceException("基础房屋数据新增失败");
                            }
                        } else {
                            BigDecimal depositMoney = house.getDepositMoney();
                            gwjBaseHouse.setDepositMoney(gwjBaseHouse.getDepositMoney().add(depositMoney));
                            // if (ObjectUtil.isEmpty(baseHouse.getUsedMoney()) ||
                            // baseHouse.getUsedMoney().equals(BigDecimal.ZERO)) {
                            // String configValue =
                            // com.yida.common.core.text.Convert.toStr(redisService.getCacheObject(GwjCacheConstants.GWJ_CONFIG_KEY
                            // + GwjCacheConstants.BLOCKED_MONEY_KEY));
                            // baseHouse.setBlockedMoney(depositMoney.multiply(new BigDecimal(configValue)));
                            // }
                            gwjBaseHouse.setCurrentMoney(null != gwjBaseHouse.getCurrentMoney() ? gwjBaseHouse.getCurrentMoney().add(depositMoney) : depositMoney);
                            if (1 != gwjBaseHouseService.updateGwjBaseHouse(gwjBaseHouse)) {
                                throw new ServiceException("基础房屋数据修改失败");
                            }
                        }
                    } else {
                        GwjBaseHouse baseHouse = gwjBaseHouseService.selectGwjBaseHouseByGwjBaseHouseId(house.getHouseId());
                        if (ObjectUtil.isNotNull(baseHouse)) {
                            BigDecimal depositMoney = null != house.getDepositMoney() ? house.getDepositMoney() : new BigDecimal("0.00");
                            baseHouse.setDepositMoney(depositMoney.add(baseHouse.getDepositMoney() == null ? new BigDecimal("0.00") : baseHouse.getDepositMoney()));
                            baseHouse.setCurrentMoney(null != baseHouse.getCurrentMoney() ? baseHouse.getCurrentMoney().add(depositMoney) : depositMoney);
                            // if (ObjectUtil.isEmpty(baseHouse.getUsedMoney()) ||
                            // baseHouse.getUsedMoney().equals(BigDecimal.ZERO)) {
                            if (StringUtils.isNull(baseHouse.getUsedMoney()) || baseHouse.getUsedMoney().compareTo(BigDecimal.ZERO) == 0) {// 20230726
                                String configValue = com.yida.common.core.text.Convert.toStr(redisService.getCacheObject(GwjCacheConstants.GWJ_CONFIG_KEY + GwjCacheConstants.BLOCKED_MONEY_KEY));
                                baseHouse.setBlockedMoney(depositMoney.multiply(new BigDecimal(configValue)));
                            }
                            gwjBaseHouseService.updateGwjBaseHouse(baseHouse);
                        }
                    }
                });
            }
            // 设置业务状态
            business.setStatus(GwjBusinessStatus.FINISH.getCode());
            // 更新业务日志
            gwjDepositBusinessLogService.addFinishLog(business);
        }
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息提交失败");
        }

    }

    /**
     * 业务修改
     *
     * @param editRequest 修改参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editBusiness(GwjUnitDepositEditRequest editRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(editRequest.getBusinessRequest().getBizId());
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(business.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        // 受理修改
        if (business.getStepId().equals(GwjUnitDepositStepEnum.ACCEPTED.getStepId())) {
            // 拷贝业务参数
            BeanUtil.copyProperties(editRequest.getBusinessRequest(), business);
            // 保存业务日志信息
            gwjDepositBusinessLogService.addSaveLog(business);

        } else
        // 初审更新
        if (GwjUnitDepositStepEnum.TRIAL.getStepId().equals(business.getStepId())) {
            List<GwjUnitDepositBusinessDetailEditRequest> detailsRequest = editRequest.getDetailsRequest();
            // 校验参数
            if (ObjectUtil.isEmpty(detailsRequest)) {
                throw new ServiceException("请填写缴存明细");
            }
            // 合计缴存金额
            BigDecimal depositMoney = new BigDecimal("0.00");
            List<GwjDepositBusinessDetail> details = new ArrayList<GwjDepositBusinessDetail>(detailsRequest.size());
            for (GwjUnitDepositBusinessDetailEditRequest detail : detailsRequest) {
                GwjDepositBusinessDetail gwjDepositBusinessDetail = new GwjDepositBusinessDetail();
                BeanUtil.copyProperties(detail, gwjDepositBusinessDetail);
                gwjDepositBusinessDetail.setBizId(business.getBizId());
                gwjDepositBusinessDetail.setMoneyId(money.getBizMoneyId());
                gwjDepositBusinessDetail.setBizNum(business.getBizNum());
                details.add(gwjDepositBusinessDetail);
            }
            if (ObjectUtil.isEmpty(details)) {
                throw new ServiceException("缴存详情不能为空");
            }
            for (GwjDepositBusinessDetail detail : details) {
                depositMoney = depositMoney.add(detail.getDepositMoney());
            }
            // 重置业务缴存明细
            gwjDepositBusinessDetailMapper.deleteBatchGwjDepositBusinessDetailByBizId(business.getBizId());
            // 新增业务缴存明细
            if (0 == gwjDepositBusinessDetailMapper.insertBatchGwjDepositBusinessDetail(details)) {
                throw new ServiceException("业务缴费详情更新失败");
            }
            // 更新业务金额信息
            money.setFactMoney(depositMoney);
            money.setDepositTime(null == money.getDepositTime() ? DateUtils.getNowDate() : money.getDepositTime());
            business.setLackMoney(business.getLackMoney().subtract(money.getFactMoney()));
            if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
                throw new ServiceException("业务金额信息更新失败");
            }
        } else
        // 财务对账修改
        if (GwjUnitDepositStepEnum.FINANCIAL_RECONCILIATION.getStepId().equals(business.getStepId())) {
            List<GwjDepositBusinessDetail> details = gwjDepositBusinessDetailMapper.selectGwjDepositBusinessDetailByBizId(business.getBizId());
            if (ObjectUtil.isEmpty(details)) {
                throw new ServiceException("未查询到对应业务缴存详情");
            }
            List<GwjUnitDepositBusinessDetailEditRequest> detailsRequest = editRequest.getDetailsRequest();
            details = details.stream().map(detail -> {
                detailsRequest.forEach(detailRequest -> {
                    if (detail.getDepositDetailId().equals(detailRequest.getDepositDetailId())) {
                        detail.setBuildInfo(detailRequest.getBuildInfo());
                        detail.setCompanyName(detailRequest.getCompanyName());
                    }
                });
                return detail;
            }).collect(Collectors.toList());
            for (GwjDepositBusinessDetail detail : details) {
                if (1 != gwjDepositBusinessDetailMapper.updateGwjDepositBusinessDetail(detail)) {
                    throw new ServiceException("业务缴存详情更新失败");
                }
            }
        } else {
            throw new ServiceException("当前业务步骤不允许更新业务信息");
        }

        // 处理业务参数
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务修改失败");
        }

    }

    /**
     * 查询基础楼栋信息
     *
     * @param communityId 社区主键
     * @return
     */
    @Override
    public List<GwjBaseBuild> getGwjBaseBuildDetailList(Long communityId) {
        GwjBaseBuildRequest request = new GwjBaseBuildRequest();
        PageUtils.startPage();
        request.setCommunityId(communityId);
        return gwjBaseBuildMapper.selectGwjBaseBuildDetailList(request);
    }

    /**
     * 选择楼栋
     *
     * @param bizId 业务主键
     * @param buildIds 楼栋主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void chooseBaseBuild(Long bizId, Long[] buildIds) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        // 校验当前步骤能否修改楼栋信息
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不能操作选择楼栋功能");
        }
        // 校验楼栋信息
        List<GwjBaseBuild> gwjBaseBuilds = gwjBaseBuildMapper.selectGwjBaseBuildByBuildIdList(buildIds);
        if (ObjectUtil.isEmpty(gwjBaseBuilds) && gwjBaseBuilds.size() != buildIds.length) {
            throw new ServiceException("楼栋信息有误，请重新选择");
        }
        // 判断楼栋是否已选择
        if (ObjectUtil.isNotEmpty(gwjDepositBusinessBuildMapper.judgeBuildChoose(bizId, buildIds))) {
            throw new ServiceException("该业务楼栋已选中，请勿重复选中");
        }
        // 查询业务小区信息
        GwjDepositBusinessCommunity gwjDepositBusinessCommunity = new GwjDepositBusinessCommunity();
        gwjDepositBusinessCommunity.setBizId(bizId);
        GwjDepositBusinessCommunity community = gwjDepositBusinessCommunityMapper.selectGwjDepositBusinessCommunity(gwjDepositBusinessCommunity);
        if (ObjectUtil.isEmpty(community)) {
            throw new ServiceException("未查询到对应业务小区");
        }
        // 查询业务业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务楼栋信息
        List<GwjDepositBusinessBuild> businessBuilds = gwjBaseBuilds.stream().map(item -> {
            GwjDepositBusinessBuild build = new GwjDepositBusinessBuild();
            build.setBizId(bizId);
            build.setBizCommunityId(community.getBizCommunityId());
            BeanUtil.copyProperties(item, build);
            build.setCalculateDataId(money.getCalculateTypeId());
            return build;
        }).collect(Collectors.toList());
        // 赋值缴费标准
        // 保存业务楼栋信息
        if (0 == gwjDepositBusinessBuildMapper.insertGwjDepositBusinessBuilds(businessBuilds)) {
            throw new ServiceException("楼栋信息导入失败");
        }
        // 处理业务楼栋房屋信息
        String[] buildCode = businessBuilds.stream().map(GwjDepositBusinessBuild::getBuildCode).toArray(String[]::new);
        Map<String, Long> buildMap = businessBuilds.stream().collect(Collectors.toMap(GwjBaseBusinessBuild::getBuildCode, GwjDepositBusinessBuild::getBuildId));
        if (ObjectUtil.isEmpty(buildCode)) {
            throw new ServiceException("楼栋编号不能为空");
        }
        // 查询基础房屋信息
        List<GwjBaseHouse> baseHouses = gwjBaseHouseService.selectGwjBaseListByBuildCodesAndAreaId(buildCode, business.getAreaId());
        // 拷贝业务房屋参数
        List<GwjDepositBusinessHouse> houses = baseHouses.stream().map(baseHouse -> {
            GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
            BeanUtil.copyProperties(baseHouse, house);
            house.setBizId(business.getBizId());
            house.setBuildId(buildMap.get(house.getBuildCode()));
            house.setDepositSize(null != house.getActualSize() && !new BigDecimal("0.00").equals(house.getActualSize()) ? house.getActualSize() : null != house.getForecastSize() && !new BigDecimal("0.00").equals(house.getForecastSize()) ? house.getForecastSize() : new BigDecimal("0.00"));
            // 默认选中模式
            house.setSelectFlag(GwjConstants.YES);
            if (ObjectUtil.isEmpty(house.getPublicFlag())) {
                house.setPublicFlag(GwjConstants.NO);
            }
            house.setDepositMoney(new BigDecimal("0.00"));
            return house;
        }).collect(Collectors.toList());
        // 保存业务房屋信息
        if (0 == gwjDepositBusinessHouseMapper.insertGwjDepositBusinessHouses(houses)) {
            throw new ServiceException("业务房屋信息导入失败");
        }
        money.setTotalMoney(new BigDecimal("0.00"));
        money.setTotalSize(new BigDecimal("0.00"));
        money.setTotalOwner(null != money.getTotalOwner() ? money.getTotalOwner() + Long.valueOf(houses.size()) : Long.valueOf(houses.size()));
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息重置失败");
        }
        // 重置业务信息
        business.setLackMoney(new BigDecimal("0.00"));
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }

    }

    /**
     * 财务对账
     *
     * @param bizId 业务主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void financeCheck(Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        // 检验步骤
        if (checkStepConfigInfo(business.getStepId(), StepConfigInfoEnum.FINANCE_CHECK.getCode())) {
            throw new ServiceException("当前步骤不允许操作财务对账");
        }
        // 查询业务金额
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(bizId);
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("请保存业务金额信息");
        }
        // 查询业务缴费详情
        List<GwjDepositBusinessDetail> details = gwjDepositBusinessDetailMapper.selectGwjDepositBusinessDetailByBizId(bizId);
        if (ObjectUtil.isEmpty(details)) {
            throw new ServiceException("请保存业务缴费详情信息");
        }
        // 校验缴存信息
        if (!money.getTotalMoney().equals(money.getFactMoney())) {
            throw new ServiceException("对账失败，实缴金额与应交金额不相等，请重新核对");
        }
        // 合计缴存明细已交金额
        BigDecimal detailTotalDepositMoney = new BigDecimal("0.00");
        for (GwjDepositBusinessDetail detail : details) {
            detailTotalDepositMoney = detailTotalDepositMoney.add(detail.getDepositMoney());
        }
        // 校验缴存明细
        if (!money.getFactMoney().equals(detailTotalDepositMoney)) {
            throw new ServiceException("对账失败，实缴金额与已交金额总数不相等，请重新核对");
        }
        // 修改业务金额缴费状态
        money.setDepositStatus(GwjDepositStatusEnum.YES.getCode());
        money.setStatus(GwjCheckAccountStatus.CHECK_SUCCESS.getCode());
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("财务对账失败");
        }
        // 修改业务房屋信息
        GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
        house.setBizId(bizId);
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(house);
        if (ObjectUtil.isEmpty(houseList)) {
            throw new ServiceException("未查询到对应业务房屋信息");
        }
        houseList = houseList.stream().map(item -> {
            item.setLackMoney(new BigDecimal("0.00"));
            return item;
        }).collect(Collectors.toList());
        for (GwjDepositBusinessHouse gwjDepositBusinessHouse : houseList) {
            if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(gwjDepositBusinessHouse)) {
                throw new ServiceException("房屋更新失败");
            }
        }
        // 修改总账、分账对账状态
        if (!gwjDepositBusinessService.edisLedgerStatus(bizId, money.getStatus())) {
            throw new ServiceException("总账、分账对账状态修改失败");
        }

    }

    /**
     * 根据标准计算楼栋房屋
     *
     * @param gwjCalculateRequest 计算标准
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void calculateHouse(GwjCalculateRequest gwjCalculateRequest) {
        // 校验权限
        Long bizId = gwjCalculateRequest.getBizId();
        GwjDepositBusiness business = checkPermission(bizId);
        String[] buildCodes = gwjCalculateRequest.getBuildCodes();
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前业务步骤不允许重新计算房屋缴交金额");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(bizId);
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("请保存业务金额信息");
        }
        // 查询业务楼栋
        GwjDepositBusinessBuild gwjDepositBusinessBuild = new GwjDepositBusinessBuild();
        gwjDepositBusinessBuild.setBizId(bizId);
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildList(gwjDepositBusinessBuild).stream().filter(item -> !GwjConstants.YES.equals(item.getPublicFlag())).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(builds)) {
            throw new ServiceException("未查询到对应非公用楼栋信息");
        }
        for (GwjDepositBusinessBuild build : builds) {
            if (null == build.getBuildType() || build.getBuildType() == 0) {
                throw new ServiceException("请选择楼栋类型后，再进行计算");
            }
        }
        Map<String, GwjDepositBusinessBuild> buildMap = builds.stream().collect(Collectors.toMap(GwjDepositBusinessBuild::getBuildCode, Function.identity()));
        Map<Long, GwjConfCalculateType> calculateTypeMap = builds.stream().map(item -> {
            // 查询计算标准公式
            GwjConfCalculateType gwjCommonCalculateType = remoteGwjConfigService.selectGwjConfCalculateTypeByCalculateTypeId(item.getCalculateDataId(), SecurityConstants.INNER).getData();
            if (StringUtils.isNull(gwjCommonCalculateType)) {
                throw new ServiceException("查无计算标准");
            }
            return gwjCommonCalculateType;
        }).collect(Collectors.toMap(GwjConfCalculateType::getCalculateTypeId, Function.identity(), (v1, v2) -> v1));
        // 查询其他计算标准
        GwjConfCalculateType otherCalculateType = remoteGwjConfigService.selectGwjConfCalculateTypeByCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID, SecurityConstants.INNER).getData();
        if (ObjectUtil.isEmpty(calculateTypeMap.get(otherCalculateType.getCalculateTypeId()))) {
            calculateTypeMap.put(otherCalculateType.getCalculateTypeId(), otherCalculateType);
        }
        // 查询业务房屋信息
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseListByBizIdAndBuildCode(bizId, buildCodes);
        Double publicDepositMoney = houseList.stream().filter(item -> GwjConstants.YES.equals(item.getPublicFlag())).map(GwjDepositBusinessHouse::getDepositMoney).mapToDouble(BigDecimal::doubleValue).sum();
        houseList = houseList.stream().filter(item -> !GwjConstants.YES.equals(item.getPublicFlag())).collect(Collectors.toList());
        houseList = houseList.stream().map(item -> {
            item.setCalculateTypeId(buildMap.get(item.getBuildCode()).getCalculateDataId());
            return item;
        }).collect(Collectors.toList());
        // 查询涉及总金额
        BigDecimal totalDepositMoney = new BigDecimal("0.00");
        // 查询设计面积
        BigDecimal totalSize = new BigDecimal("0.00");
        // 查询涉及户数
        Long totalOwner = 0L;
        // 处理业务房屋信息
        for (GwjDepositBusinessHouse house : houseList) {
            // 平摊
            if ("2".equals(calculateTypeMap.get(house.getCalculateTypeId()).getGetValFlag())) {
                // 排除未选择
                if (house.getSelectFlag().equals(GwjConstants.NO)) {
                    continue;
                }
                totalOwner += 1;
                // 计算总面积
                totalSize = gwjDepositBusinessHouseMapper.countTotalSizeByBizIdAndBuildCodes(bizId, buildCodes);
                // 对象转换为map并计算
                Map<String, Object> temp = BeanUtil.beanToMap(house);
                temp.put("totalMoney", money.getTotalMoney());
                temp.put("totalSize", totalSize);
                house.setDepositMoney(GwjCalculateFormulaUtil.getFormulaResult(calculateTypeMap.get(house.getCalculateTypeId()).getFormula(), temp));
                // house.setDepositSize(null != house.getActualSize() && !new
                // BigDecimal("0.00").equals(house.getActualSize())
                // ? house.getActualSize() : null != house.getForecastSize() && !new
                // BigDecimal("0.00").equals(house.getForecastSize())
                // ? house.getForecastSize() : new BigDecimal("0.00"));
                house.setLackMoney(house.getDepositMoney());
                // 更新房屋数据
                gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(house);
                // 缴存金额累计，用于计算差额
                totalDepositMoney = totalDepositMoney.add(house.getDepositMoney());

            } else {
                // 查询楼栋信息
                GwjDepositBusinessBuild build = buildMap.get(house.getBuildCode());
                // 查询计算标准值
                GwjConfCalculateData gwjCommonCalculateData = remoteGwjConfigService.selectCalculateDataByCalculateTypeIdAndAreaIdAndBuildTypeId(build.getCalculateDataId(), build.getAreaId(), build.getBuildType(), SecurityConstants.INNER).getData();
                // 查询楼栋下非公用户房屋
                if (GwjConstants.YES.equals(house.getPublicFlag())) {
                    continue;
                }
                // 排除未选择
                if (house.getSelectFlag().equals(GwjConstants.NO)) {
                    continue;
                }
                totalOwner += 1;
                // 设置缴存面积
                // house.setDepositSize(null != house.getActualSize() && !new
                // BigDecimal("0.00").equals(house.getActualSize())
                // ? house.getActualSize() : null != house.getForecastSize() && !new
                // BigDecimal("0.00").equals(house.getForecastSize())
                // ? house.getForecastSize() : new BigDecimal("0.00"));
                if ("1".equals(calculateTypeMap.get(house.getCalculateTypeId()).getGetValFlag()) && ObjectUtil.isEmpty(gwjCalculateRequest.getOtherCalculateVal())) {
                    if (StringUtils.isNull(gwjCommonCalculateData)) {
                        throw new ServiceException("查无计算标准值");
                    }
                    house.setCalculateVal(gwjCommonCalculateData.getCalculateVal());
                    // 对象转换为map并计算
                    house.setDepositMoney(GwjCalculateFormulaUtil.getFormulaResult(calculateTypeMap.get(house.getCalculateTypeId()).getFormula(), BeanUtil.beanToMap(house)));
                } else if ("0".equals(calculateTypeMap.get(house.getCalculateTypeId()).getGetValFlag()) || ObjectUtil.isNotEmpty(gwjCalculateRequest.getOtherCalculateVal())) {
                    if (StringUtils.isNull(gwjCalculateRequest.getOtherCalculateVal()) || gwjCalculateRequest.getOtherCalculateVal().equals(BigDecimal.ZERO)) {
                        throw new ServiceException("请输入计算标准金额");
                    }
                    house.setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
                    house.setCalculateVal(gwjCalculateRequest.getOtherCalculateVal());
                    // 对象转换为map并计算
                    house.setDepositMoney(GwjCalculateFormulaUtil.getFormulaResult(calculateTypeMap.get(house.getCalculateTypeId()).getFormula(), BeanUtil.beanToMap(house)));
                }
                // 更新数据
                house.setLackMoney(house.getDepositMoney());
                gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(house);
                // 缴存金额累计，用于计算差额
                totalDepositMoney = totalDepositMoney.add(house.getDepositMoney());
                // 计算总面积
                totalSize = gwjDepositBusinessHouseMapper.countTotalSizeByBizIdAndBuildCodes(bizId, buildCodes);
            }
        }
        // 当选择其他计算标准是修改业务楼栋计算标准
        if (gwjCalculateRequest.getCalculateTypeId().equals(GwjConstants.IMPORT_HOUSE_CALCULATE_ID) && null != gwjCalculateRequest.getOtherCalculateVal()) {
            for (GwjDepositBusinessBuild build : builds) {
                build.setCalculateDataId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
                // 更新业务楼栋信息
                if (1 != gwjDepositBusinessBuildMapper.updateGwjDepositBusinessBuild(build)) {
                    throw new ServiceException("业务楼栋信息修改失败");
                }
            }
        }
        // 修改业务金额 实际金额
        money.setTotalMoney(totalDepositMoney.add(new BigDecimal(publicDepositMoney)));
        money.setTotalSize(totalSize);
        money.setTotalOwner(totalOwner);
        gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money);
        // 修改业务差额
        business.setLackMoney(money.getTotalMoney().subtract(money.getFactMoney()));
        gwjDepositBusinessMapper.updateGwjDepositBusiness(business);

    }

    /**
     * 回退
     *
     * @param businessLog 回退信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void fallback(GwjDepositBusinessLog businessLog) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(businessLog.getBizId());
        Long stepId = business.getStepId();
        Long lastStepId = 0L;
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务");
        }
        // 校验步骤
        // 受理步骤回退
        if (GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(stepId)) {
            throw new ServiceException("当前业务步骤是第一步，不能再回退");
        } else
        // 初审步骤回退
        if (GwjUnitDepositStepEnum.TRIAL.getStepId().equals(stepId)) {
            lastStepId = GwjUnitDepositStepEnum.ACCEPTED.getStepId();
            // 重置金额、缴费详情信息
            GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
            money.setBizId(business.getBizId());
            money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
            if (ObjectUtil.isEmpty(money)) {
                throw new ServiceException("未查询到业务金额信息");
            }
            // 处理业务金额信息
            money.setFactMoney(new BigDecimal("0.00"));
            money.setFactSize(new BigDecimal("0.00"));
            money.setInterestCalculation(0);
            // 更新业务金额信息
            if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
                throw new ServiceException("业务金额信息回退失败");
            }
            // 重置业务差额信息
            business.setLackMoney(money.getTotalMoney());
            // 设置回退步骤
            business.setStepId(GwjUnitDepositStepEnum.ACCEPTED.getStepId());
            // 重置缴费详情信息
            if (ObjectUtil.isNotEmpty(gwjDepositBusinessDetailMapper.selectGwjDepositBusinessDetailByBizId(business.getBizId()))) {
                if (0 == gwjDepositBusinessDetailMapper.deleteBatchGwjDepositBusinessDetailByBizId(business.getBizId())) {
                    throw new ServiceException("业务缴费详情回退失败");
                }
            }
        } else
        // 财务对账回退
        if (GwjUnitDepositStepEnum.FINANCIAL_RECONCILIATION.getStepId().equals(stepId)) {
            lastStepId = GwjUnitDepositStepEnum.TRIAL.getStepId();
            // 回退业务金额信息
            GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
            money.setBizId(business.getBizId());
            money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
            if (ObjectUtil.isEmpty(money)) {
                throw new ServiceException("未查询到业务金额信息");
            }
            // 处理业务金额信息
            money.setStatus(GwjCheckAccountStatus.NOT_CHECK.getCode());
            money.setDepositStatus(GwjDepositStatusEnum.NO.getCode());
            // 更新业务回退信息
            if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
                throw new ServiceException("业务金额信息回退失败");
            }
            // 回退业务房屋信息
            GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
            house.setBizId(business.getBizId());
            List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(house);
            if (ObjectUtil.isEmpty(houseList)) {
                throw new ServiceException("未查询到对应业务房屋信息");
            }
            // 处理业务房屋信息
            houseList = houseList.stream().map(item -> {
                item.setLackMoney(item.getDepositMoney());
                return item;
            }).collect(Collectors.toList());
            for (GwjDepositBusinessHouse gwjDepositBusinessHouse : houseList) {
                // 回退房屋信息
                if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(gwjDepositBusinessHouse)) {
                    throw new ServiceException("业务房屋回退失败");
                }
            }
            // 设置回退步骤
            business.setStepId(GwjUnitDepositStepEnum.TRIAL.getStepId());
            // 查询缴费详情
            List<GwjDepositBusinessDetail> details = gwjDepositBusinessDetailMapper.selectGwjDepositBusinessDetailByBizId(business.getBizId());
            if (ObjectUtil.isEmpty(details)) {
                throw new ServiceException("未查询到对应缴费详情");
            }
            // 计算已缴金额
            BigDecimal depositMoney = new BigDecimal("0.00");
            for (GwjDepositBusinessDetail detail : details) {
                depositMoney = depositMoney.add(detail.getDepositMoney());
            }
            // 重置差额
            // business.setLackMoney(business.getLackMoney().add(depositMoney));
            // 重置总账、分账流水
            if (!gwjDepositBusinessService.removeLedger(business.getBizId())) {
                throw new ServiceException("总账、分账流水重置失败");
            }
        } else if (GwjUnitDepositStepEnum.CASE_REVIEW.getStepId().equals(stepId)) {
            throw new ServiceException("当前业务已完结,不能再回退");
        } else {
            throw new ServiceException("当前业务步骤状态错误");
        }

        // 设置日志的当前步骤
        businessLog.setStepId(business.getStepId());
        // 修改业务当前办理人员为上一个流程的最终提交人
        GwjUserDTO user = gwjDepositBusinessLogService.getPreviousSubmitUser(business.getBizId(), lastStepId);
        if (ObjectUtil.isEmpty(user)) {
            throw new ServiceException("未查询到上步骤操作人");
        }
        business.setCurrentOperId(user.getUserId());
        business.setCurrentOperName(user.getRealName());
        // 设置回退状态
        business.setStatus(GwjBusinessStatus.FALLBACK.getCode());
        gwjDepositBusinessMapper.updateGwjDepositBusiness(business);
        // 保存回退日志
        businessLog.setRealName(user.getRealName());
        businessLog.setUserId(user.getUserId());
        gwjDepositBusinessLogService.addFallbackLog(businessLog);
    }

    /**
     * 业务详情
     *
     * @param bizId 业务主键
     * @return
     */
    @Override
    public GwjUnitDepositDetailDTO getDetail(Long bizId) {
        // 查询业务、金额、缴费详情、小区、楼栋信息
        GwjDepositBusiness business = gwjDepositBusinessMapper.selectGwjDepositBusinessByBizId(bizId);
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(bizId);
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        List<GwjDepositBusinessDetail> details = gwjDepositBusinessDetailMapper.selectGwjDepositBusinessDetailByBizId(bizId);
        GwjDepositBusinessCommunity community = new GwjDepositBusinessCommunity();
        community.setBizId(bizId);
        community = gwjDepositBusinessCommunityMapper.selectGwjDepositBusinessCommunity(community);
        GwjDepositBusinessBuild build = new GwjDepositBusinessBuild();
        build.setBizId(bizId);
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildList(build);
        // 处理业务参数
        GwjUnitDepositDetailDTO result = new GwjUnitDepositDetailDTO();
        GwjDepositBusinessDetailDTO businessDetail = new GwjDepositBusinessDetailDTO();
        GwjDepositCommunityDetailDTO communityDetail = new GwjDepositCommunityDetailDTO();
        GwjDepositMoneyDetailDTO moneyDetail = new GwjDepositMoneyDetailDTO();
        // 拷贝业务参数
        BeanUtil.copyProperties(business, businessDetail);
        BeanUtil.copyProperties(money, moneyDetail);
        BeanUtil.copyProperties(community, communityDetail);
        List<GwjUnitDepositBuildDetailDTO> buildDetails = builds.stream().map(item -> {
            GwjUnitDepositBuildDetailDTO detailDTO = new GwjUnitDepositBuildDetailDTO();
            BeanUtil.copyProperties(item, detailDTO);
            return detailDTO;
        }).collect(Collectors.toList());
        List<GwjDepositPaymentDetailDTO> paymentDetails = details.stream().map(item -> {
            GwjDepositPaymentDetailDTO paymentDetail = new GwjDepositPaymentDetailDTO();
            BeanUtil.copyProperties(item, paymentDetail);
            return paymentDetail;
        }).collect(Collectors.toList());
        // 赋值业务参数
        result.setBusinessDetail(businessDetail);
        result.setMoneyDetail(moneyDetail);
        result.setPaymentDetails(paymentDetails);
        result.setCommunityDetail(communityDetail);
        result.setBuildDetails(buildDetails);
        return result;
    }

    /**
     * 删除案例
     *
     * @param bizId 业主主键
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeBusiness(Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        business.setStatus(GwjBusinessStatus.FINISH.getCode());
        int i = gwjDepositBusinessMapper.updateGwjDepositBusiness(business);
        if (1 != i) {
            throw new ServiceException("案例删除失败");
        }
        return i;
    }

    /**
     * 删页
     *
     * @param bizId 业务主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBusinessData(Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 判断是否存在业务
        if (ObjectUtil.isEmpty(business)) {
            throw new ServiceException("未查询到对应业务信息");
        }
        // 判断当期步骤是否能删页
        if (checkStepConfigInfo(business.getStepId(), StepConfigInfoEnum.DELETE_PAGE.getCode())) {
            throw new ServiceException("当前业务步骤不能删页");
        }
        // 删除对应业务小区、楼栋、房屋、信息
        gwjDepositBusinessCommunityMapper.deleteGwjDepositBusinessCommunityByBizId(bizId);
        gwjDepositBusinessBuildMapper.deleteGwjDepositBusinessBuildByBizId(bizId);
        gwjDepositBusinessHouseMapper.deleteGwjDepositBusinessHouseByBizId(bizId);
        // 重置日志信息
        gwjDepositBusinessLogService.deleteGwjDepositBusinessLogByBizId(bizId);
        // 重置业务参数
        business.setApplicantName("");
        business.setPhone("");
        business.setBizName("");
        business.setArchivesNum("");
        business.setLackMoney(new BigDecimal("0.00"));
        business.setCommentFlag(GwjConstants.NO);
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        business.setApplicantTime(DateUtils.getNowDate());
        // 更新业务参数
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务数据重置失败");
        }
        // 查询业务金额参数
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 设置常量
        BigDecimal zero = new BigDecimal("0.00");
        // 重置业务金额参数
        money.setTotalMoney(zero);
        money.setFactMoney(zero);
        money.setFactSize(zero);
        money.setTotalSize(zero);
        money.setDepositObject("业主个人缴存");
        money.setCapitalProperty("普通商住房");
        money.setStatus("0");
        money.setDepositTime(null);
        money.setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
        money.setAccountTime(null);
        money.setTotalOwner(0L);
        // 更新业务金额参数
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额重置失败");
        }

    }

    /**
     * 资金分户房屋列表头部
     *
     * @param gwjDepositBusinessHouse
     * @return
     */
    @Override
    public GwjDepositBusinessHouseTopDTO getHouseDetailTop(GwjDepositBusinessHouse gwjDepositBusinessHouse) {
        GwjDepositBusinessHouseTopDTO dto = new GwjDepositBusinessHouseTopDTO();
        // 获取房屋信息
        gwjDepositBusinessHouse.setSelectFlag(GwjConstants.YES);
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(gwjDepositBusinessHouse);
        // 处理业务参数
        BigDecimal totalActualSize = new BigDecimal("0.00");
        BigDecimal totalForecastSize = new BigDecimal("0.00");
        BigDecimal totalDepositMoney = new BigDecimal("0.00");
        Integer totalOwner = houseList.size();
        // 赋值业务参数
        for (GwjDepositBusinessHouse house : houseList) {
            totalActualSize = totalActualSize.add(null == house.getActualSize() ? new BigDecimal("0.00") : house.getActualSize());
            totalForecastSize = totalForecastSize.add(null == house.getForecastSize() ? new BigDecimal("0.00") : house.getForecastSize());
            totalDepositMoney = totalDepositMoney.add(null == house.getDepositMoney() ? new BigDecimal("0.00") : house.getDepositMoney());
        }
        dto.setTotalActualSize(totalActualSize);
        dto.setTotalForecastSize(totalForecastSize);
        dto.setTotalDepositMoney(totalDepositMoney);
        dto.setTotalOwner(totalOwner);
        return dto;
    }

    /**
     * 查询缴存清册头部
     *
     * @param bizId 业务主键
     * @return
     */
    @Override
    public GwjDepositRecordTopDTO getDepositRecordTop(Long bizId) {
        return gwjDepositBusinessMapper.getDepositRecord(bizId);
    }

    /**
     * 查询小区分户清册头部
     *
     * @param bizId 业务主键
     * @return
     */
    @Override
    public GwjCommunityHouseholdRecordTopDTO getCommunityHouseholdRecordTop(Long bizId) {
        return gwjDepositBusinessMapper.getCommunityHouseholdRecord(bizId);
    }

    /**
     * 资金分户修改房屋缴费面积
     *
     * @param calculateHouseRequest 缴费免息参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editCalculateHouse(GwjUnitDepositEditCalculateHouseRequest calculateHouseRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(calculateHouseRequest.getBizId());
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不能修改房屋缴费面积");
        }
        // 查询业务房屋信息
        GwjDepositBusinessHouse gwjDepositBusinessHouse = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseByBizHouseId(calculateHouseRequest.getBizHouseId());
        if (ObjectUtil.isEmpty(gwjDepositBusinessHouse)) {
            throw new ServiceException("未查询到对应业务房屋信息");
        }
        if (GwjConstants.YES.equals(gwjDepositBusinessHouse.getPublicFlag())) {
            throw new ServiceException("公用房屋缴费面积无法修改");
        }
        // 查询业务楼栋信息
        GwjBaseBuild gwjBaseBuild = gwjBaseBuildMapper.selectGwjBaseBuildByBuildId(gwjDepositBusinessHouse.getBuildId());
        if (ObjectUtil.isEmpty(gwjBaseBuild)) {
            throw new ServiceException("未查询到对应楼栋信息");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(calculateHouseRequest.getBizId());
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 查询计算标准公式
        GwjConfCalculateType gwjCommonCalculateType = remoteGwjConfigService.selectGwjConfCalculateTypeByCalculateTypeId(gwjDepositBusinessHouse.getCalculateTypeId(), SecurityConstants.INNER).getData();
        if (StringUtils.isNull(gwjCommonCalculateType)) {
            throw new ServiceException("请先完成计算标准");
        }
        // 修改业务金额信息
        money.setTotalSize(money.getTotalSize().subtract(gwjDepositBusinessHouse.getDepositSize()).add(calculateHouseRequest.getDepositSize()));
        money.setTotalMoney(money.getTotalMoney().subtract(gwjDepositBusinessHouse.getDepositMoney()));
        // 修改业务房屋缴费面积
        gwjDepositBusinessHouse.setDepositSize(calculateHouseRequest.getDepositSize());
        // 计算缴费金额
        BigDecimal depositMoney = GwjCalculateFormulaUtil.getFormulaResult(gwjCommonCalculateType.getFormula(), BeanUtil.beanToMap(gwjDepositBusinessHouse));
        // 修改业务房屋应缴费金额
        gwjDepositBusinessHouse.setDepositMoney(depositMoney);
        // 修改业务金额应缴金额
        money.setTotalMoney(money.getTotalMoney().add(depositMoney));
        // 修改业务应缴金额
        business.setLackMoney(money.getTotalMoney());
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息更新失败");
        }
        // 业更新业务房屋信息
        if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(gwjDepositBusinessHouse)) {
            throw new ServiceException("业务房屋信息修改失败");
        }
    }

    /**
     * 导入房屋信息
     *
     * @param file 导入文件
     * @param bizId 业务主键
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importHouseInfo(MultipartFile file, Long bizId) {
        // 验证权限
        gwjDepositBusinessService.checkPermission(bizId);
        // 判断导入文件是否为空
        if (file.isEmpty()) {
            // return "导入房屋文件不能为空！";
            throw new ServiceException("导入房屋文件不能为空！");
        }
        // 校验导入文件类型
        try {
            if (!checkImportFile(file)) {
                // return "不是指定的xlsx，xls导入类型文件！";
                throw new ServiceException("不是指定的xlsx，xls导入类型文件！");
            }
        } catch (Exception e) {
            throw new ServiceException("不是指定的xlsx，xls导入类型文件！");
        }
        // 处理导入数据
        ExcelUtil<GwjUnitDepositBusinessExcelVo> util = new ExcelUtil<>(GwjUnitDepositBusinessExcelVo.class);
        List<GwjUnitDepositBusinessExcelVo> importHouses = new ArrayList<GwjUnitDepositBusinessExcelVo>();
        try {
            importHouses = util.importExcel(file.getInputStream());
        } catch (Exception e) {
            throw new ServiceException("导入文件错误");
        }
        // 判断导入房屋数据是否为空
        if (ObjectUtil.isEmpty(importHouses)) {
            throw new ServiceException("导入房屋数据不能为空");
        }
        // 查询业务房屋数据
        GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
        house.setBizId(bizId);
        house.setPublicFlag(GwjConstants.NO);
        house.setSelectFlag(GwjConstants.YES);
        List<GwjDepositBusinessHouse> houses = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(house);
        if (ObjectUtil.isEmpty(houses)) {
            throw new ServiceException("未查询到对应业务房屋数据");
        }
        // 判断导入条数是否与业务数据相等
        if (houses.size() != importHouses.size()) {
            throw new ServiceException("导入数据条数与业务房屋条数不一致");
        }
        // 赋值业务数据
        List<GwjDepositBusinessHouse> newHouses = new ArrayList<GwjDepositBusinessHouse>(houses.size());
        for (GwjDepositBusinessHouse gwjDepositBusinessHouse : houses) {
            for (GwjUnitDepositBusinessExcelVo importHouse : importHouses) {
                if (gwjDepositBusinessHouse.getHouseId().equals(importHouse.getHouseId())) {
                    gwjDepositBusinessHouse.setDepositSize(importHouse.getDepositSize());
                    newHouses.add(gwjDepositBusinessHouse);
                }
            }
        }
        // 处理导入信息
        List<GwjUnitDepositEditCalculateHouseRequest> houseRequestList = newHouses.stream().map(item -> {
            GwjUnitDepositEditCalculateHouseRequest houseRequest = new GwjUnitDepositEditCalculateHouseRequest();
            houseRequest.setBizId(bizId);
            houseRequest.setBizHouseId(item.getBizHouseId());
            houseRequest.setDepositSize(item.getDepositSize());
            return houseRequest;
        }).collect(Collectors.toList());
        houseRequestList.forEach(this::editCalculateHouse);
        return "恭喜您，数据已全部导入成功！共 " + houseRequestList.size() + " 条！";
    }

    /**
     * 修改业务小区信息
     *
     * @param editRequest 修改参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editCommunityAndBuild(GwjUnitDepositCommunityAndBuildEditRequest editRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(editRequest.getBizId());
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改业务信息");
        }
        // 处理业务小区、楼栋信息
        GwjUnitDepositCommunityEditRequest communityRequest = editRequest.getCommunityRequest();
        // List<GwjUnitDepositBusinessBuildEditRequest> buildRequests = editRequest.getBuildRequests();
        // 重置业务小区、楼栋、房屋数据
        gwjDepositBusinessCommunityMapper.deleteGwjDepositBusinessCommunityByBizId(business.getBizId());
        gwjDepositBusinessBuildMapper.deleteGwjDepositBusinessBuildByBizId(business.getBizId());
        gwjDepositBusinessHouseMapper.deleteGwjDepositBusinessHouseByBizId(business.getBizId());
        // 查询业务金额信息
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(editRequest.getBizId());
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 拉取基础数据
        // 拉取社区基础数据
        GwjBaseCommunity gwjBaseCommunity = gwjBaseCommunityMapper.selectGwjBaseCommunityByGwjBaseCommunityId(communityRequest.getCommunityId());
        // // 拉取楼栋信息
        // List<GwjBaseBuild> gwjBaseBuilds =
        // gwjBaseBuildMapper.selectGwjBaseBuildByBuildIdList(buildRequests.stream().map(GwjUnitDepositBusinessBuildEditRequest::getBuildId).toArray(Long[]::new));
        // // 拉取房屋信息
        // List<GwjBaseHouse> baseHouses =
        // gwjBaseHouseService.selectGwjBaseListByBuildCodesAndAreaId(gwjBaseBuilds.stream().map(GwjBaseBuild::getBuildCode).toArray(String[]::new),
        // communityRequest.getAreaId());
        // // 拷贝小区参数
        GwjDepositBusinessCommunity community = new GwjDepositBusinessCommunity();
        BeanUtil.copyProperties(gwjBaseCommunity, community);
        BeanUtil.copyProperties(communityRequest, community);
        community.setBizId(editRequest.getBizId());
        // 新增业务小区信息
        if (1 != gwjDepositBusinessCommunityMapper.insertGwjDepositBusinessCommunity(community)) {
            throw new ServiceException("业务小区新增失败");
        }
        // // 处理楼栋信息
        // List<GwjDepositBusinessBuild> builds = gwjBaseBuilds.stream().map(item -> {
        // GwjDepositBusinessBuild build = new GwjDepositBusinessBuild();
        // BeanUtil.copyProperties(item, build);
        // build.setBizCommunityId(community.getBizCommunityId());
        // return build;
        // }).collect(Collectors.toList());
        // // 拷贝楼栋信息参数
        // builds = builds.stream().map(item -> {
        // for (GwjUnitDepositBusinessBuildEditRequest buildRequest : buildRequests) {
        // if (buildRequest.getBuildId().equals(item.getBuildId())) {
        // BeanUtil.copyProperties(buildRequest, item);
        // item.setBizCommunityId(community.getBizCommunityId());
        // item.setBizId(business.getBizId());
        // }
        // }
        // return item;
        // }).collect(Collectors.toList());
        // // 新增楼栋信息
        // if (0 == gwjDepositBusinessBuildMapper.insertGwjDepositBusinessBuilds(builds)) {
        // throw new ServiceException("业务楼栋新增失败");
        // }
        // Map<String, Long> buildMap = builds.stream().collect(Collectors.toMap(GwjDepositBusinessBuild::getBuildCode,
        // GwjDepositBusinessBuild::getBuildId));
        // // 处理楼栋房屋信息
        // List<GwjDepositBusinessHouse> houses = baseHouses.stream().map(item -> {
        // GwjDepositBusinessHouse house = new GwjDepositBusinessHouse();
        // BeanUtil.copyProperties(item, house);
        // house.setBizId(business.getBizId());
        // house.setSelectFlag(GwjConstants.YES);
        // house.setBuildId(buildMap.get(house.getBuildCode()));
        // return house;
        // }).collect(Collectors.toList());
        // // 新增房屋信息
        // if (0 == gwjDepositBusinessHouseMapper.insertGwjDepositBusinessHouses(houses)) {
        // throw new ServiceException("业务房屋新增失败");
        // }
        // 设置常量
        BigDecimal zero = new BigDecimal("0.00");
        // 处理业务金额参数
        money.setTotalMoney(zero);
        money.setFactMoney(zero);
        money.setFactSize(zero);
        money.setTotalSize(zero);
        money.setDepositObject("业主个人缴存");
        money.setCapitalProperty("普通商住房");
        money.setStatus("0");
        money.setDepositTime(null);
        money.setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
        money.setAccountTime(null);
        money.setTotalOwner(0L);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额修改失败");
        }
        // 处理业务参数
        business.setLackMoney(new BigDecimal("0.00"));
        business.setStatus(GwjBusinessStatus.NORMAL.getCode());
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息修改失败");
        }
    }

    /**
     * 删除楼栋
     *
     * @param bizId 业务主键
     * @param bizBuildIds 楼栋主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBuildData(Long bizId, Long[] bizBuildIds) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 查询业务楼栋
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.judgeBuildChoose(bizId, bizBuildIds);
        String[] buildCodes = builds.stream().map(GwjBaseBusinessBuild::getBuildCode).toArray(String[]::new);
        // 查询业务房屋
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseListByBizIdAndBuildCode(bizId, buildCodes);
        Long[] bizHouseIds = houseList.stream().map(GwjDepositBusinessHouse::getBizHouseId).toArray(Long[]::new);
        // 计算删除楼栋面积、缴费金额
        BigDecimal totalMoney = new BigDecimal("0.00");
        BigDecimal totalDepositSize = new BigDecimal("0.00");
        for (GwjDepositBusinessHouse house : houseList) {
            totalMoney = totalMoney.add(null != house.getDepositMoney() ? house.getDepositMoney() : new BigDecimal("0.00"));
            totalDepositSize = totalDepositSize.add(null != house.getDepositSize() ? house.getDepositSize() : new BigDecimal("0.00"));
        }
        // 删除业务房屋
        if (0 != bizHouseIds.length) {
            if (0 == gwjDepositBusinessHouseMapper.deleteGwjDepositBusinessHouseByBizHouseIds(bizHouseIds)) {
                throw new ServiceException("业务房屋删除失败");
            }
        }
        // 删除业务楼栋
        if (0 == gwjDepositBusinessBuildMapper.deleteGwjDepositBusinessBuildByBizBuildIds(builds.stream().map(GwjDepositBusinessBuild::getBizBuildId).toArray(Long[]::new))) {
            throw new ServiceException("业务楼栋删除失败");
        }
        // 重置业务金额信息
        GwjDepositBusinessMoney money = new GwjDepositBusinessMoney();
        money.setBizId(bizId);
        money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(money);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        money.setTotalMoney(null != money.getTotalMoney() && !new BigDecimal("0.00").equals(money.getTotalMoney()) ? money.getTotalMoney().subtract(totalMoney) : new BigDecimal("0.00"));
        money.setTotalSize(null != money.getTotalSize() && !new BigDecimal("0.00").equals(money.getTotalSize()) ? money.getTotalSize().subtract(totalDepositSize) : new BigDecimal("0.00"));
        money.setTotalOwner(null != money.getTotalOwner() && money.getTotalOwner() != 0L ? money.getTotalOwner() - Long.valueOf(houseList.size()) : 0L);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息重置失败");
        }
        // 重置业务信息
        business.setLackMoney(null != business.getLackMoney() && !new BigDecimal("0.00").equals(business.getLackMoney()) ? business.getLackMoney().subtract(totalMoney) : new BigDecimal("0.00"));
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }

    }

    /**
     * 缴费标准主键
     *
     * @param calculateRequest 修改参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editMoneyCalculate(GwjUnitDepositEditMoneyCalculateRequest calculateRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(calculateRequest.getBizId());
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改缴费标准");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(business.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 查询业务楼栋信息
        GwjDepositBusinessBuild gwjDepositBusinessBuild = new GwjDepositBusinessBuild();
        gwjDepositBusinessBuild.setBizId(business.getBizId());
        List<GwjDepositBusinessBuild> builds = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildList(gwjDepositBusinessBuild).stream().filter(item -> !GwjConstants.YES.equals(item.getPublicFlag())).collect(Collectors.toList());
        // 查询业务房屋信息
        GwjDepositBusinessHouse gwjDepositBusinessHouse = new GwjDepositBusinessHouse();
        gwjDepositBusinessHouse.setBizId(business.getBizId());
        List<GwjDepositBusinessHouse> houses = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(gwjDepositBusinessHouse);
        // 设置常量
        BigDecimal zero = new BigDecimal("0.00");
        // 处理业务信息
        business.setLackMoney(zero);
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息修改失败");
        }
        // 处理业务金额
        money.setCalculateTypeId(calculateRequest.getCalculateTypeId());
        money.setTotalMoney(zero);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息修改失败");
        }
        // 处理业务楼栋信息
        builds = builds.stream().map(item -> {
            item.setCalculateDataId(calculateRequest.getCalculateTypeId());
            return item;
        }).collect(Collectors.toList());
        // 更新业务楼栋信息
        builds.forEach(item -> {
            if (1 != gwjDepositBusinessBuildMapper.updateGwjDepositBusinessBuild(item)) {
                throw new ServiceException("业务楼栋信息修改失败");
            }
        });
        // 重置房屋缴费标准
        houses = houses.stream().map(item -> {
            item.setCalculateTypeId(null);
            item.setCalculateVal(null);
            item.setDepositMoney(zero);
            return item;
        }).collect(Collectors.toList());
        // 更新业务房屋信息
        houses.forEach(item -> {
            if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(item)) {
                throw new ServiceException("业务房屋信息修改失败");
            }
        });
    }

    /**
     * 修改业务楼栋
     *
     * @param editRequest 修改参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editBuildCalculateAndBuildType(GwjUnitDepositEditBuildCalculateRequest editRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(editRequest.getBizId());
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改业务楼栋信息");
        }
        // 设置常量
        BigDecimal zero = new BigDecimal("0.00");
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(business.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额
        money.setTotalMoney(zero);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息更新失败");
        }
        // 查询业务楼栋信息
        GwjDepositBusinessBuild build = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildByBizBuildId(editRequest.getBizBuildId());
        if (ObjectUtil.isEmpty(build)) {
            throw new ServiceException("未查询到对应业务楼栋信息");
        }
        if (GwjConstants.YES.equals(build.getPublicFlag())) {
            throw new ServiceException("公用户楼栋不允许修改");
        }
        // 处理业务楼栋信息
        build.setCalculateDataId(null != editRequest.getCalculateTypeId() ? editRequest.getCalculateTypeId() : build.getCalculateDataId());
        build.setBuildType(null != editRequest.getBuildType() ? editRequest.getBuildType() : build.getBuildType());
        // 更新业务楼栋信息
        if (1 != gwjDepositBusinessBuildMapper.updateGwjDepositBusinessBuild(build)) {
            throw new ServiceException("业务楼栋信息修改失败");
        }
        // 查询业务房屋信息
        GwjDepositBusinessHouse gwjDepositBusinessHouse = new GwjDepositBusinessHouse();
        gwjDepositBusinessHouse.setBizId(editRequest.getBizId());
        gwjDepositBusinessHouse.setBuildId(build.getBuildId());
        gwjDepositBusinessHouse.setBuildCode(build.getBuildCode());
        List<GwjDepositBusinessHouse> houses = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseList(gwjDepositBusinessHouse);
        // 重置房屋缴费标准
        houses = houses.stream().map(item -> {
            item.setCalculateTypeId(null);
            item.setCalculateVal(null);
            item.setDepositMoney(zero);
            return item;
        }).collect(Collectors.toList());
        // 更新业务房屋信息
        houses.forEach(item -> {
            if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(item)) {
                throw new ServiceException("业务房屋信息修改失败");
            }
        });
    }

    /**
     * 创建公用户楼栋
     *
     * @param gwjPublicAccountRequest 创建参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPublicBuild(GwjPublicAccountRequest gwjPublicAccountRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(gwjPublicAccountRequest.getBizId());
        // 查询业务小区
        GwjDepositBusinessCommunity gwjDepositBusinessCommunity = new GwjDepositBusinessCommunity();
        gwjDepositBusinessCommunity.setBizId(gwjPublicAccountRequest.getBizId());
        GwjDepositBusinessCommunity community = gwjDepositBusinessCommunityMapper.selectGwjDepositBusinessCommunity(gwjDepositBusinessCommunity);
        // 判断小区是否为空
        if (ObjectUtil.isEmpty(community)) {
            throw new ServiceException("未查询到对应业务小区信息");
        }
        // 创建公用户楼栋
        GwjDepositBusinessBuild gwjDepositBusinessBuild = new GwjDepositBusinessBuild() {
            {
                setBuildName(gwjPublicAccountRequest.getBuildName());
                setBuildNo(gwjPublicAccountRequest.getBuildName());
                setBizId(gwjPublicAccountRequest.getBizId());
                setAreaId(community.getAreaId());
                setStreetId(community.getStreetId());
                setBizCommunityId(community.getBizCommunityId());
                setPublicCreateTime(DateUtils.getNowDate());
                setBuildType(GwjConstants.PUBLIC_BUILD_TYPE);
                setPublicFlag(GwjConstants.YES);
                setCalculateDataId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
                setBuildCode(GwjCustomImportConstants.PUBLIC_HOUSE + gwjImpSqeService.reserveSqeByIndex("build", 1L));
                setTotalLayer(0);
                setTotalOwner(0);
                setNonResidence(0);
                setResidence(0);
                setPeriodSize(new BigDecimal("0.00"));
                setTotalSize(new BigDecimal("0.00"));
            }
        };
        // 新增公用楼栋
        if (1 != gwjDepositBusinessBuildMapper.insertGwjDepositBusinessBuild(gwjDepositBusinessBuild)) {
            throw new ServiceException("公用楼栋创建失败");
        }
        // 创建公用房屋
        GwjDepositBusinessHouse gwjDepositBusinessHouse = new GwjDepositBusinessHouse() {
            {
                setBizId(gwjPublicAccountRequest.getBizId());
                setDepositMoney(gwjPublicAccountRequest.getPublicMoney());
                setRoomNum(gwjPublicAccountRequest.getRoomNum());
                setBuildName(gwjDepositBusinessBuild.getBuildName());
                setAreaId(community.getAreaId());
                setStreetId(community.getStreetId());
                setForecastSize(new BigDecimal("0.00"));
                setBuildCode(gwjDepositBusinessBuild.getBuildCode());
                setSelectFlag(GwjBusinessHouseStatus.CONFIRM.getCode());
                setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
                setCalculateVal(new BigDecimal("0.00"));
                setHouseCode(GwjCustomImportConstants.PUBLIC_HOUSE + gwjImpSqeService.reserveSqeByIndex("house", 1L));
                setNominalLayer("0");
                setUseType("公用户");
                setHouseLocation(community.getCommunityName() + gwjPublicAccountRequest.getBuildName() + "(" + gwjPublicAccountRequest.getRoomNum() + ")");
                setPublicCreateTime(DateUtils.getNowDate());
                setPublicFlag(GwjConstants.YES);
            }
        };
        // 新增公用房屋
        if (1 != gwjDepositBusinessHouseMapper.insertGwjDepositBusinessHouse(gwjDepositBusinessHouse)) {
            throw new ServiceException("公用房屋创建失败");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(gwjPublicAccountRequest.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        // 判断业务金额是否为空
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额
        money.setTotalMoney(null != money.getTotalMoney() ? money.getTotalMoney().add(gwjDepositBusinessHouse.getDepositMoney()) : new BigDecimal("0.00").add(gwjDepositBusinessHouse.getDepositMoney()));
        money.setTotalOwner(null != money.getTotalOwner() ? money.getTotalOwner() + 1 : 1);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额更新失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() ? business.getLackMoney().add(gwjDepositBusinessHouse.getDepositMoney()) : new BigDecimal("0.00").add(gwjDepositBusinessHouse.getDepositMoney()));
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }
    }

    /**
     * 房屋维护-加入选择
     *
     * @param bizHouseIds 业务房屋主键
     * @param bizId 业务主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void houseMaintainConfirmSelect(Long[] bizHouseIds, Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改房屋数据");
        }
        // 处理业务房屋信息
        int ownerCount = 0;
        BigDecimal totalSize = new BigDecimal("0.00");
        BigDecimal totalMoney = new BigDecimal("0.00");
        for (Long bizHouseId : bizHouseIds) {
            GwjDepositBusinessHouse gwjDepositBusinessHouse = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseByBizHouseId(bizHouseId);
            if (StringUtils.isNotNull(gwjDepositBusinessHouse)) {
                ownerCount += 1;
                totalSize = totalSize.add(null != gwjDepositBusinessHouse.getActualSize() ? gwjDepositBusinessHouse.getActualSize() : new BigDecimal("0.00"));
                totalMoney = totalMoney.add(null != gwjDepositBusinessHouse.getDepositMoney() ? gwjDepositBusinessHouse.getDepositMoney() : new BigDecimal("0.00"));
                // 修改选择状态
                gwjDepositBusinessHouse.setSelectFlag(GwjBusinessHouseStatus.CONFIRM.getCode());
                // 更新业务金额信息
                if (1 != gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(gwjDepositBusinessHouse)) {
                    throw new ServiceException("业务房屋信息修改失败");
                }
            }
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额信息
        money.setTotalSize(null != money.getTotalSize() ? money.getTotalSize().add(totalSize) : totalSize);
        money.setTotalOwner(null != money.getTotalOwner() ? money.getTotalOwner() + ownerCount : ownerCount);
        money.setTotalMoney(null != money.getTotalMoney() ? money.getTotalMoney().add(totalMoney) : totalMoney);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额修改失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() ? business.getLackMoney().add(totalMoney) : totalMoney);
        // 更新业务数据
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息修改失败");
        }
    }

    /**
     * 房屋维护-取消选择
     *
     * @param bizHouseIds 业务房屋主键
     * @param bizId 业务主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void houseMaintainCancelSelect(Long[] bizHouseIds, Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改房屋数据");
        }
        // 处理业务房屋信息
        int ownerCount = 0;
        BigDecimal totalSize = new BigDecimal("0.00");
        BigDecimal totalMoney = new BigDecimal("0.00");
        for (Long bizHouseId : bizHouseIds) {
            GwjDepositBusinessHouse gwjDepositBusinessHouse = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseByBizHouseId(bizHouseId);
            if (StringUtils.isNotNull(gwjDepositBusinessHouse)) {
                ownerCount += 1;
                totalSize = totalSize.add(null != gwjDepositBusinessHouse.getActualSize() ? gwjDepositBusinessHouse.getActualSize() : new BigDecimal("0.00"));
                totalMoney = totalMoney.add(null != gwjDepositBusinessHouse.getDepositMoney() ? gwjDepositBusinessHouse.getDepositMoney() : new BigDecimal("0.00"));
                // 修改选择状态
                gwjDepositBusinessHouse.setSelectFlag(GwjBusinessHouseStatus.CANCEL.getCode());
                gwjDepositBusinessHouse.setCalculateVal(new BigDecimal("0.00"));
                gwjDepositBusinessHouse.setDepositMoney(new BigDecimal("0.00"));
                gwjDepositBusinessHouse.setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
                gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(gwjDepositBusinessHouse);
            }
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额信息
        money.setTotalSize(null != money.getTotalSize() ? money.getTotalSize().subtract(totalSize) : new BigDecimal("0.00"));
        money.setTotalOwner(null != money.getTotalOwner() ? money.getTotalOwner() - ownerCount : 0);
        money.setTotalMoney(null != money.getTotalMoney() ? money.getTotalMoney().subtract(totalMoney) : new BigDecimal("0.00"));
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额修改失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() ? business.getLackMoney().subtract(totalMoney) : new BigDecimal("0.00"));
        // 更新业务数据
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息修改失败");
        }
    }

    /**
     * 创建公用户房屋
     * 
     * @param gwjPublicAccountRequest 创建公用房屋参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPublicHouse(GwjPublicAccountRequest gwjPublicAccountRequest) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(gwjPublicAccountRequest.getBizId());
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许创建公用户房屋数据");
        }
        // 查询业务小区信息
        GwjDepositBusinessCommunity gwjDepositBusinessCommunity = new GwjDepositBusinessCommunity();
        gwjDepositBusinessCommunity.setBizId(gwjPublicAccountRequest.getBizId());
        GwjDepositBusinessCommunity community = gwjDepositBusinessCommunityMapper.selectGwjDepositBusinessCommunity(gwjDepositBusinessCommunity);
        if (ObjectUtil.isEmpty(community)) {
            throw new ServiceException("未查询到对应业务楼栋");
        }
        // 查询业务楼栋信息
        GwjDepositBusinessBuild build = gwjDepositBusinessBuildMapper.selectGwjDepositBusinessBuildByBizBuildId(gwjPublicAccountRequest.getBizBuildId());
        if (ObjectUtil.isEmpty(build)) {
            throw new ServiceException("未查询到对应楼栋信息");
        }
        // 处理业公用户屋信息
        GwjDepositBusinessHouse house = new GwjDepositBusinessHouse() {
            {
                setBizId(gwjPublicAccountRequest.getBizId());
                setBuildCode(build.getBuildCode());
                setAreaId(community.getAreaId());
                setStreetId(community.getStreetId());
                setDepositMoney(gwjPublicAccountRequest.getPublicMoney());
                setLackMoney(gwjPublicAccountRequest.getPublicMoney());
                setRoomNum(gwjPublicAccountRequest.getRoomNum());
                setHouseCode(GwjCustomImportConstants.PUBLIC_HOUSE + gwjImpSqeService.reserveSqeByIndex("house", 1L));
                setSelectFlag(GwjBusinessHouseStatus.CONFIRM.getCode());
                setNominalLayer("0");
                setUseType("公用户");
                setForecastSize(new BigDecimal("0.00"));
                setHouseLocation(community.getCommunityName() + build.getBuildName() + "(" + gwjPublicAccountRequest.getRoomNum() + ")");
                setPublicCreateTime(DateUtils.getNowDate());
                setPublicFlag(GwjConstants.YES);
                setCalculateTypeId(GwjConstants.IMPORT_HOUSE_CALCULATE_ID);
            }
        };
        // 新增公用户房屋信息
        if (1 != gwjDepositBusinessHouseMapper.insertGwjDepositBusinessHouse(house)) {
            throw new ServiceException("新增公用户房屋失败");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(gwjPublicAccountRequest.getBizId());
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额信息
        money.setTotalMoney(null != money.getTotalMoney() ? money.getTotalMoney().add(house.getDepositMoney()) : house.getDepositMoney());
        money.setTotalOwner(null != money.getTotalOwner() ? money.getTotalOwner() + 1L : 1L);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息更新失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() ? business.getLackMoney().add(house.getDepositMoney()) : house.getDepositMoney());
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }

    }

    /**
     * 编辑公用户房屋
     * 
     * @param houseRequests 公用户房屋修改参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePublicHouse(List<GwjPublicBusinessHouseRequest> houseRequests) {
        // 判断参数是否为空
        if (ObjectUtil.isEmpty(houseRequests)) {
            throw new ServiceException("公用户房屋修改参数不能为空");
        }
        Long bizId = houseRequests.get(0).getBizId();
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许修改公用户房屋数据");
        }
        // 查询业务公用房屋信息
        Long[] bizHouseIds = houseRequests.stream().map(GwjPublicBusinessHouseRequest::getBizHouseId).toArray(Long[]::new);
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseListByBizIds(bizHouseIds);
        if (ObjectUtil.isEmpty(houseList)) {
            throw new ServiceException("未查询到对应公用户房屋信息");
        }
        houseList.forEach(item -> {
            if (GwjConstants.NO.equals(item.getPublicFlag())) {
                throw new ServiceException("当前业务中存在非公用户房屋");
            }
        });
        // 计算更新前公用户房屋缴款金额(过滤未选中公用房屋数据)
        BigDecimal oldTotalDepositMoney = new BigDecimal(houseList.stream().filter(item -> GwjConstants.YES.equals(item.getSelectFlag())).map(GwjDepositBusinessHouse::getDepositMoney).mapToDouble(BigDecimal::doubleValue).sum());
        // 计算更新后公用户房屋缴款金额(过滤未选中公用房屋数据)
        BigDecimal newTotalDepositMoney = new BigDecimal(houseRequests.stream().filter(item -> {
            for (GwjDepositBusinessHouse house : houseList) {
                // 判断未选中是过滤
                if (house.getBizHouseId().equals(item.getBizHouseId()) && GwjConstants.YES.equals(house.getSelectFlag())) {
                    return true;
                } else {
                    return false;
                }
            }
            return false;
        }).map(GwjPublicBusinessHouseRequest::getDepositMoney).mapToDouble(BigDecimal::doubleValue).sum());
        // 处理公用户房屋信息
        houseList.forEach(item -> {
            for (GwjPublicBusinessHouseRequest houseRequest : houseRequests) {
                if (item.getBizHouseId().equals(houseRequest.getBizHouseId())) {
                    item.setHouseLocation(houseRequest.getHouseLocation());
                    item.setDepositMoney(houseRequest.getDepositMoney());
                }
            }
            // 更新公用户房屋信息
            gwjDepositBusinessHouseMapper.updateGwjDepositBusinessHouse(item);
        });
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额信息
        money.setTotalMoney(null != money.getTotalMoney() && !new BigDecimal("0.00").equals(money.getTotalMoney()) ? money.getTotalMoney().subtract(oldTotalDepositMoney).add(newTotalDepositMoney) : newTotalDepositMoney);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额更新失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() && !new BigDecimal("0.00").equals(business.getLackMoney()) ? business.getLackMoney().subtract(oldTotalDepositMoney).add(newTotalDepositMoney) : newTotalDepositMoney);
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }
    }

    /**
     * 删除公用户房屋
     * 
     * @param bizHouseIds 业务房屋主键
     * @param bizId 业务主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePublicHouse(Long[] bizHouseIds, Long bizId) {
        // 校验权限
        GwjDepositBusiness business = checkPermission(bizId);
        // 校验步骤
        if (!GwjUnitDepositStepEnum.ACCEPTED.getStepId().equals(business.getStepId())) {
            throw new ServiceException("当前步骤不允许删除公用户房屋数据");
        }
        // 校验参数
        if (0 == bizHouseIds.length) {
            throw new ServiceException("请选中删除房屋");
        }
        // 查询业务公用户房屋信息
        List<GwjDepositBusinessHouse> houseList = gwjDepositBusinessHouseMapper.selectGwjDepositBusinessHouseListByBizIds(bizHouseIds);
        // 判断业务公用房屋数据是否一致
        if (bizHouseIds.length != houseList.size()) {
            throw new ServiceException("公用户房屋信息有误，请重新选择");
        }
        // 计算公用户房屋缴款金额（过滤未选中房屋）
        BigDecimal totalDepositMoney = new BigDecimal(houseList.stream().filter(item -> GwjConstants.YES.equals(item.getSelectFlag())).map(GwjDepositBusinessHouse::getDepositMoney).mapToDouble(BigDecimal::doubleValue).sum());
        // 删除业务公用户房屋
        if (0 == gwjDepositBusinessHouseMapper.deleteGwjDepositBusinessHouseByBizHouseIds(bizHouseIds)) {
            throw new ServiceException("公用户房屋删除失败");
        }
        // 查询业务金额信息
        GwjDepositBusinessMoney gwjDepositBusinessMoney = new GwjDepositBusinessMoney();
        gwjDepositBusinessMoney.setBizId(bizId);
        GwjDepositBusinessMoney money = gwjDepositBusinessMoneyMapper.selectGwjDepositBusinessMoney(gwjDepositBusinessMoney);
        if (ObjectUtil.isEmpty(money)) {
            throw new ServiceException("未查询到对应业务金额信息");
        }
        // 处理业务金额信息
        money.setTotalMoney(null != money.getTotalMoney() && !new BigDecimal("0.00").equals(money.getTotalMoney()) ? money.getTotalMoney().subtract(totalDepositMoney) : new BigDecimal("0.00"));
        // 处理业务户数（过滤未选中房屋）
        money.setTotalOwner(null != money.getTotalOwner() && 0L != money.getTotalOwner() ? money.getTotalOwner() - Long.valueOf(houseList.stream().filter(item -> GwjConstants.YES.equals(item.getSelectFlag())).collect(Collectors.toList()).size()) : 0L);
        // 更新业务金额信息
        if (1 != gwjDepositBusinessMoneyMapper.updateGwjDepositBusinessMoney(money)) {
            throw new ServiceException("业务金额信息更新失败");
        }
        // 处理业务信息
        business.setLackMoney(null != business.getLackMoney() && !new BigDecimal("0.00").equals(business.getLackMoney()) ? business.getLackMoney().subtract(totalDepositMoney) : new BigDecimal("0.00"));
        // 更新业务信息
        if (1 != gwjDepositBusinessMapper.updateGwjDepositBusiness(business)) {
            throw new ServiceException("业务信息更新失败");
        }
    }

    /**
     * 校验用户权限
     *
     * @param bizId 业主主键
     * @return
     */
    private GwjDepositBusiness checkPermission(Long bizId) {
        Long currentUserId = SecurityUtils.getUserId();
        GwjDepositBusiness gwjDepositBusiness = gwjDepositBusinessMapper.selectGwjDepositBusinessByBizId(bizId);
        if (StringUtils.isNull(gwjDepositBusiness) || !GwjBusinessFlagType.UNIT_DEPOSIT.getCode().equals(gwjDepositBusiness.getBizFlagId())) {
            throw new ServiceException("查无相关业务");
        }
        if (!currentUserId.equals(gwjDepositBusiness.getCurrentOperId()) && currentUserId != 1) {
            throw new ServiceException("当前办事员没有权限操作本业务");
        }
        return gwjDepositBusiness;
    }

    /**
     * 校验步骤
     *
     * @param stepId 步骤主键
     * @param stepConfigInfo 操作信息
     * @return
     */
    private Boolean checkStepConfigInfo(Long stepId, String stepConfigInfo) {
        List<String> configInfos = remoteGwjConfigService.selectGwjConfStepConfigInfoCodeListByBizFlagId(stepId, SecurityConstants.INNER).getData();
        if (!StringUtils.containsAny(configInfos, stepConfigInfo)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 检测导入文件类型是否合规
     *
     * @param file 文件
     * @return /
     * @throws Exception /
     */
    private boolean checkImportFile(MultipartFile file) throws Exception {
        // 检查文件类型
        String type = FileTypeUtils.getExtension(file);
        // 限制的文件类型集合
        return StringUtils.inStringIgnoreCase(type, "xlsx", "xls");
    }
}
